﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace EITSurferInfinityLib
{
    public class FramesWriter
    {
        /// <summary>
        /// Point toward target directory
        /// </summary>
        public string DirPath;
        /// <summary>
        /// Current file index
        /// </summary>
        int CounterFile;
        /// <summary>
        /// Current position in the current file 
        /// </summary>
        int CounterInFile;
        /// <summary>
        /// Maximum number of frames per file .frames
        /// </summary>
        int MaxNumberFile;
        /// <summary>
        /// Extension of the files
        /// </summary>
        string Extension;
        /// <summary>
        /// File name
        /// </summary>
        string FileName;
        /// <summary>
        /// name  of the manifest file
        /// </summary>
        string ManifestName;

        List<int> Manifest;

        public FramesWriter(string extension, int maxNumberFile, string dirPath)
        {
            DirPath=dirPath;
            CounterFile = 0;
            CounterInFile = 0;
            MaxNumberFile = maxNumberFile;
            FileName = "data";
            Extension = extension;
            ManifestName = "manifest.dat";
            Manifest = new List<int>();
            Setup();
        }


        #region public methods
        public void Add(byte [] data, Int64 TimeStamp, int configPointer)
        {
            DirectoryInfo di = new DirectoryInfo(DirPath);

            if (!di.Exists)
            {
                Directory.CreateDirectory(DirPath);
            }

            BinaryWriter bw = new BinaryWriter(File.Open(DirPath +"\\"+ GetFileName(), FileMode.Append));
            {
                bw.Write(data.Length);
                bw.Write(TimeStamp);
                bw.Write(configPointer);
                bw.Write(data);
                AddAFrame();
            }
            bw.Close();
            WriteManifest();
        }
        #endregion

        #region private methods
        void WriteManifest()
        {
            BinaryWriter bw = new BinaryWriter(File.Open(DirPath + "\\" +ManifestName, FileMode.OpenOrCreate));
            {
                for (int i = 0; i < Manifest.Count; i++)
                {
                    bw.Write(Manifest[i]);
                }
            }
            bw.Close();
        }
        void ReadManifest()
        {
            Manifest.Clear();
            BinaryReader br = new BinaryReader(File.Open(DirPath + "\\" + ManifestName, FileMode.Open));
            {
                for (int i = 0; i < br.BaseStream.Length/4; i++)
                {
                    Manifest.Add(br.ReadInt32());
                }
            }
            br.Close();
        }
        void AddAFile()
        {
            CounterFile++;
            CounterInFile = 0;
            Manifest.Add(0);
        }
        void AddAFrame()
        {
            CounterInFile++;
            Manifest[Manifest.Count-1]++;
            Debug.WriteLine(Manifest[Manifest.Count - 1].ToString());
        }
        string GetFileName()
        {
            if (CounterInFile == MaxNumberFile)
            {
                AddAFile();
            }
            string s = FileName + CounterFile.ToString() + Extension;
            return s;
        }

        void Setup()
        {
            if (DirPath != null)
            {
                DirectoryInfo di = new DirectoryInfo(DirPath);

                if (!di.Exists)
                {
                    Directory.CreateDirectory(DirPath);
                }

                di.Refresh();

                FileInfo[] fi = di.GetFiles();
                bool AsManifest = false;

                for (int i = 0; i < fi.Length; i++)
                {
                    if (fi[i].Name == ManifestName)
                    {
                        AsManifest = true;
                    }
                }

                if (AsManifest)
                {
                    ReadManifest();
                    CounterInFile = Manifest[Manifest.Count - 1];

                    CounterFile = fi.Length - 1 - 1;  // zero based anb substract the manifest file
                }
                else
                {
                    Manifest.Clear();
                    Manifest.Add(0);
                    CounterFile = fi.Length;
                }
            }
            else
            {
                Manifest.Clear();
                Manifest.Add(0);
                CounterFile = 0;
            }
        }
        #endregion
    }
}
